#include "ConfigParser.h"
#include <iostream>
#include "AnalysesHeaders.h"
#include <string>
ConfigParser::ConfigParser(){

name="NoName";
RunName="NoName";
DataType="None";
bool doGRL=false;
}	

ConfigParser::~ConfigParser(){
	
TH1FKeys.clear();
TH1FMap.clear();
TH2FKeys.clear();
TH2FMap.clear();
AnaMap.clear();
CfgFileList.clear();
//KinKeys.clear();
//KinMap.clear();	

}


std::vector<std::string> ConfigParser::getTH1FKeys(){
	
return TH1FKeys;	
}

std::map<std::string,TH1F*> ConfigParser::getTH1FMap(){	
return TH1FMap;
};


std::vector<std::string> ConfigParser::getTH2FKeys(){
	
return TH2FKeys;	
}

std::map<std::string,TH2F*> ConfigParser::getTH2FMap(){	
return TH2FMap;
};



void::ConfigParser::ParseTHs(std::string fname,std::string objType){

  libconfig::Config cfg;

  // Read the file. If there is an error, report it and exit.
  try
  {
    cfg.readFile(fname.c_str());
  }
  catch(const libconfig::FileIOException &fioex)
  {
    std::cerr << "I/O error while reading configuration file." << std::endl;
    exit(EXIT_FAILURE);
  }
  catch(const libconfig::ParseException &pex)
  {
    std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
              << " - " << pex.getError() << std::endl;
    exit(EXIT_FAILURE);
  }

  const libconfig::Setting& root = cfg.getRoot();
  
 if(!objType.compare("TH1Fs")){ 
  try
  {
    const libconfig::Setting &histo_list = root[objType];
    int count = histo_list.getLength();
    
    for(int i = 0; i<count;i++){
      const libconfig::Setting &histogram = histo_list[i];
	  //std::cout<<"searching "<<objType<<"  block"<<std::endl;
      // if any field is absent give an error and exit. We are paranoiacs !
      std::string s_name, s_title;
      int s_nbins, s_xmin, s_xmax;
      if(! (histogram.lookupValue("name",s_name)
		   && histogram.lookupValue("title", s_title)
           && histogram.lookupValue("nbins", s_nbins)
           && histogram.lookupValue("xmin", s_xmin)
           && histogram.lookupValue("xmax", s_xmax) ) ){
        std::cerr<<"Error while Reading TH1Fs "<<std::endl;
        exit(EXIT_FAILURE);
      }//end of if
    
    TH1FKeys.push_back(std::string(s_name));//Fill TH1F Keys
    TH1FMap[std::string(s_name)]=new TH1F(s_name.c_str(),(s_title+" Analysis : "+ConfigParser::name).c_str(),s_nbins,s_xmin,s_xmax);//Fill TH1FMap
   
  }//end of for loop
   
 }//end of try
  
  catch(const libconfig::SettingNotFoundException &nfex)
  {
    std::cerr<<" Error Parsing TH1F block"<<std::endl;
    exit(EXIT_FAILURE);
  }
 }
 else if(!objType.compare("TH2Fs")){
	  try
  {
    const libconfig::Setting &histo_list = root[objType];
    int count = histo_list.getLength();
    
    for(int i = 0; i<count;i++){
      const libconfig::Setting &histogram = histo_list[i];
	  //std::cout<<"searching "<<objType<<"  block"<<std::endl;
      // if any field is absent give an error and exit. We are paranoiacs !
      std::string s_name, s_title;
      int s_nbinsx, s_xlow,s_ylow,s_yup, s_xup,s_nbinsy;
      if(! (histogram.lookupValue("name",s_name)
		   && histogram.lookupValue("title", s_title)
           && histogram.lookupValue("nbinsx", s_nbinsx)
           && histogram.lookupValue("nbinsy", s_nbinsy)
           && histogram.lookupValue("xlow", s_xlow)
           && histogram.lookupValue("xup", s_xup)
           && histogram.lookupValue("ylow", s_ylow)
           && histogram.lookupValue("yup", s_yup) ) ){
        std::cerr<<"Error while Reading TH2Fs "<<std::endl;
        exit(EXIT_FAILURE);
      }//end of if
    
    TH2FKeys.push_back(std::string(s_name));//Fill TH1F Keys
    TH2FMap[std::string(s_name)]=new TH2F(s_name.c_str(),s_title.c_str(),s_nbinsx,s_xlow,s_xup,s_nbinsy,s_ylow,s_yup);//Fill TH2FMap
   
  }//end of for loop
   
 }//end of try
  
  catch(const libconfig::SettingNotFoundException &nfex)
  {
    std::cerr<<" Error Parsing TH1F block"<<std::endl;
    exit(EXIT_FAILURE);
  } 
	 
}	
}

void ConfigParser::ParseAnalysisSettings(std::string fname){
  libconfig::Config cfg;

  // Read the file. If there is an error, report it and exit.
  try
  {
    cfg.readFile(fname.c_str());
  }
  catch(const libconfig::FileIOException &fioex)
  {
    std::cerr << "I/O error while reading configuration file." << std::endl;
    exit(EXIT_FAILURE);
  }
  catch(const libconfig::ParseException &pex)
  {
    std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
              << " - " << pex.getError() << std::endl;
    exit(EXIT_FAILURE);
  }
  
const libconfig::Setting& root = cfg.getRoot();  
const libconfig::Setting &settings = root["Settings"];

if( ! settings.lookupValue("name",name) ){
      std::cerr<<"***EROR ***\"name\" is mandatory setting. Check file:"<<fname<<std::endl;
      exit(-1);
  
  }

settings.lookupValue("doGRL",doGRL);

}

std::map<std::string,Analysis*> ConfigParser::getAnaMap(){
	
	return AnaMap;
}
std::vector<std::string> ConfigParser::getCfgFileList(){
	return CfgFileList;
}
void ConfigParser::PaerseRunSettings(std::string fname /*This is run configuration file*/ ){
  libconfig::Config cfg;
  // Read the file. If there is an error, report it and exit.
  try
  {
    cfg.readFile(fname.c_str());
  }
  catch(const libconfig::FileIOException &fioex)
  {
    std::cerr << "I/O error while reading configuration file." << std::endl;
    exit(EXIT_FAILURE);
  }
  catch(const libconfig::ParseException &pex)
  {
    std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
              << " - " << pex.getError() << std::endl;
    exit(EXIT_FAILURE);
  }

const libconfig::Setting& root = cfg.getRoot();
root.lookupValue("RunName",RunName);
root.lookupValue("Nevents",Nevents);
root.lookupValue("TreeName",TreeName);
root.lookupValue("DataType",ConfigParser::DataType);
const libconfig::Setting &analyses = root["Analyses"];
int count = analyses.getLength();
 for(int i = 0; i<count;i++){
 const libconfig::Setting &analysis = analyses[i];
 std::string s_configFile;
 std::string s_type;
 if(! (analysis.lookupValue("type",s_type)&&analysis.lookupValue("configFile",s_configFile))){
	 std::cerr<<"Lookup Error in Parsing Analyses"<<std::endl;
	 exit(EXIT_FAILURE);
  }
  CfgFileList.push_back(s_configFile);
  
  if(!s_type.compare("E6")){
  AnaMap[s_configFile]=new E6ANA();
  }
  else if(!s_type.compare("Generic")){
    AnaMap[s_configFile]=new GenericHistogrammer();
  }
  else if(!s_type.compare("E6-2")){
    AnaMap[s_configFile]=new E6ANA2();
  }
  else{
	std::cerr<<"Wrong Analysis type:  "<< s_type<<" Check Your Config. EXIT"<<std::endl;
	std::cout<<"(Allowed types are: Generic , E6, E6-2 )"<<std::endl;
	exit(EXIT_FAILURE);  
  
  }
 }//end of for
}

//Note of the day : 
//that should be working didnt test it yet
